home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
PROGNG_C
/
TURBOCU1.LZH
/
QBOUNC.C
< prev
next >
Wrap
Text File
|
1987-09-05
|
14KB
|
266 lines
/*
THE USE OF QLIB FUNCTIONS IN CREATING BOUNCE BAR MENUS
GARRY J. VASS [72307,3311]
Copyright (c), 1987, Telemacus Software Associates
QBOUNCE.C NOTES
---------------
This program demonstrates the use of QLIB to create
"bounce-bar" menus. These menus (and their cousins,
the "pull downs") are regarded as highly intuitive/
user-friendly. To compile this program, make a project
file that includes this program and the qlib specification.
In the interactive environment, use the <ALT-R> sequence.
QLIB registrants are urged to employ these functions as
appropriate and issue them in compiled form. The source
code, however, is protected by United States Copyright
Law and may not be distributed.
Author: Garry J. Vass [72307,3311]
BOUNCE BAR PROGRAMMING TIPS:
----------------------------
1. Keep the menu width as narrow as possible, remember
that there are two qsnap i/o's for every keystroke.
2. Try and stay on the conservative side with the
menu foreground/background attributes. A lot of
folks out there live in the mono world and can only
see 7 (white) clearly.
3. If possible, use unique first letters for your
menu choices. Future versions of QLIB will support
the "first character selection".
PREREQUISITES:
--------------
1. The TURBO C compiler, set to LARGE model. Other MAJOR
compilers will work, but any adverse outcome is
your own problem.
2. QLIB.LIB (Version 3 or higher) must be available
in order to link. If you don't have QLIB, and are
unable to find it on your favorite BBS, send your
name, address, and $35 to
Lisa T. Vass
5311 Blvd East # 3
West New York, NJ 07093
QLIB registrants receive updates for one year mailed
automatically to the address provided with no additional
action required on your part. A user-type documentation
package is also included by return mail.
3. Several registrants have observed that QLIB will work
with COMPACT, HUGE, etc. models. While these discoveries
are fun, please note that QLIB is supported in the LARGE
environment only.
*/
#define return_pressed 13 /* Variables returned by */
#define up_arrow_pressed 0x0148 /* qreadkbd(). See qfocus */
#define down_arrow_pressed 0x0150 /* screens. */
typedef unsigned char qstring[79]; /* */
typedef struct qmenustructure /* Bounce bar menu struct */
{ /* */
int screen_x; /* Upper left column */
int screen_y; /* Upper row */
int menu_width; /* Menu width in columns */
int foreground; /* Foreground color */
int background; /* Background color */
int option_count; /* Total number of options */
int prior_choice; /* Choice last call */
qstring title; /* Menu title */
qstring option_text[10]; /* Option list to max of */
} qmenurecord; /* ten. */
/* */
/* */
/* */
qmenurecord mainmenu = /* Declare and initialize in*/
{ /* one step. */
28, /* column 28 */
7, /* row 7 */
20, /* 20 columns wide */
15, /* bright white foreground */
0, /* black background */
5, /* five options (from zero) */
0, /* Never called before */
"[ MAIN MENU ]", /* Title */
"Do This", /* Option 0 */
"Do That", /* Option 1 */
"Do Something else", /* Option 2 */
"**Do Wah Diddy**", /* Option 3 */
"Do Bee Do Bee Do", /* Option 4 */
"Leave the demo" /* Option 5 */
}; /* */
qmenurecord secondary = /* Declare and initialize */
{ /* a second-level menu to */
28, /* demonstrate the threading*/
11, /* possibilities. */
30, /* */
7, /* Please remember that the */
0, /* options start at ZERO. */
4, /* */
0, /* The last option should */
"[ SECONDARY MENU ]", /* always be the exit */
"FOXTROT", /* condition. */
"TANGO", /* */
"WALTZ", /* */
"CHARLESTON", /* */
"STOP DANCING", /* */
}; /* */
void qpad(qstring st, int n) /* No frills padding, see */
{ /* QLIB 4 for fast function.*/
qstring temp = ""; /* */
qstring blank = " "; /* */
while(strlen(st) + strlen(temp) < n)
{
strcat(st, blank);
strcat(temp, blank);
}
strcat(temp, st);
strcpy(st, temp);
if (strlen(st) % 2 == n % 2) strcat(st, blank);
}
int qbounce_bar(qmenurecord *m) /* Returns an integer */
{ /* */
unsigned char normal; /* Normal/reverse get calcu-*/
unsigned char reverse; /* lated for convenience. */
int current_option = 0; /* */
unsigned int keyvar; /* See QLIB documentation */
/* */
/* */
qgotoxy(0, 25); /* */
normal = ((m ->background<<4) +
m ->foreground) & 127;
reverse = ((m ->foreground<<4) +
m ->background) & 127;
qdrawbox ( /* Draw a box to hold the */
m ->screen_x - 1, /* menu. */
m ->screen_y - 2, /* */
m ->screen_x + m ->menu_width + 1, /* */
m ->screen_y + m ->option_count + 2,/* */
m ->title, "", /* */
reverse, /* */
normal, /* */
normal); /* */
for (current_option=0; /* Pad the options to center*/
current_option<=m ->option_count; /* within the menu width */
++current_option) /* */
{ /* */
qpad(m ->option_text[current_option], /* */
m ->menu_width); /* */
qsnap /* Display the options */
( /* */
m ->option_text[current_option], /* */
m ->screen_x, /* */
m ->screen_y + current_option, /* */
normal /* */
); /* */
} /* */
keyvar = 0; /* */
current_option = m ->prior_choice; /* Set an initial value for */
while(keyvar != return_pressed) /* choice. */
{ /* */
qsnap /* Highlight the new option */
( /* */
m ->option_text[current_option], /* */
m ->screen_x, /* */
m ->screen_y + current_option, /* */
reverse /* */
); /* */
qturn_num_lock_off(); /* */
keyvar = qreadkbd(); /* Get the arrow key */
qsnap /* Unhighlight the old */
( /* option */
m ->option_text[current_option], /* */
m ->screen_x, /* */
m ->screen_y + current_option, /* Inc/dec according to the */
normal /* keystroke, and wrap */
); /* around if upper/lower */
/* limits are reached. */
/* */
/* */
/* */
if (keyvar == up_arrow_pressed ) --current_option;
if (keyvar == down_arrow_pressed) ++current_option;
if (current_option > m ->option_count) current_option = 0;
if (current_option < 0 ) current_option = m ->option_count;
} /* When a choice is made, */
m -> prior_choice = current_option; /* store it for next time */
return(current_option); /* and return it as the */
} /* function value. */
main() /* */
/* Main code begins here */
/* */
/* */
{
int mainkey = 0;
qstring mainstring = "You have elected to ";
qstring secondarystring = "You have asked me to ";
qstring hitanykey = "hit any key to continue";
int user_choice = 0;
while (user_choice != mainmenu.option_count)
{
qclrscr(15);
user_choice = qbounce_bar(&mainmenu);
qclrscr(15);
qcenter_line(mainstring, 12, 15);
qcenter_line(mainmenu.option_text[user_choice], 14, 15);
qcenter_line(hitanykey, 16, 15);
mainkey = qreadkbd();
/* */
/* */
/* This particular example */
/* will jump to a secondary */
/* menu whenever option 3 */
/* is selected. The logic */
/* to implement threading */
/* follows. Upon return, */
/* the default main menu */
/* option will be preserved.*/
/* Using this structure, */
/* menus can be nested until*/
/* the cows come home. */
/* */
/* */
if (user_choice == 3)
{
user_choice = 0;
while (user_choice != secondary.option_count)
{
qclrscr(15);
user_choice = qbounce_bar(&secondary);
qclrscr(15);
qcenter_line(secondarystring, 12, 15);
qcenter_line(secondary.option_text[user_choice], 14, 15);
qcenter_line(hitanykey, 16, 15);
mainkey = qreadkbd();
}
}
}
/* For an interesting */
/* diversion, simply delete */
/* this next line and check */
/* the error messages. */
qgotoxy(mainkey % 79, mainkey % 24);
}
m ->screen_x, /* */
m ->screen_y + current_optio